package the.workshop.bu.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.wisteria.framework.web.QueryResult;
import org.wisteria.framework.web.mvc.dto.ConditionDTO;
import org.wisteria.framework.web.mvc.service.AbstractSuperService;
import the.broccoli.setting.service.IDictService;
import the.broccoli.uc.entity.User;
import the.broccoli.uc.service.IUserService;
import the.workshop.bu.dto.*;
import the.workshop.bu.dto.req.CustomerAddReq;
import the.workshop.bu.dto.req.CustomerModifyReq;
import the.workshop.bu.dto.req.SalesQuantityReq;
import the.workshop.bu.entity.Customer;
import the.workshop.bu.entity.CustomerTax;
import the.workshop.bu.entity.CustomerTel;
import the.workshop.bu.mapper.CustomerMapper;
import the.workshop.bu.mapper.StatisticMapper;
import the.workshop.bu.service.ICreditService;
import the.workshop.bu.service.ICustomerService;
import the.workshop.bu.service.ICustomerTaxService;
import the.workshop.bu.service.ICustomerTelService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lei.liu
 * @since 2020-06-15
 */
@Slf4j
@Service
public class CustomerServiceImpl extends AbstractSuperService<CustomerMapper, Customer> implements ICustomerService {

    @Resource
    private ICustomerTelService customerTelService;

    @Resource
    private ICreditService creditService;

    @Resource
    private IDictService dictService;

    @Resource
    private ICustomerTaxService customerTaxService;

    @Resource
    private IUserService userService;

    @Resource
    private StatisticMapper statisticMapper;

    @Override
    public QueryResult<CustomerDTO> pageList(ConditionDTO condition, Integer pageNum, Integer pageSize) {
        QueryResult<CustomerDTO> queryResult = super.pageList(condition, pageNum, pageSize);
        if (!CollectionUtils.isEmpty(queryResult.getItems())) {
            for (CustomerDTO dto : queryResult.getItems()) {
                dto.setStatusName(dictService.getName(dto.getStatus()));
            }
        }
        return queryResult;
    }

    @Override
    public CustomerDTO detailById(Integer customerId) {
        CustomerCondition condition = new CustomerCondition();
        condition.setId(customerId);
        List<CustomerDTO> list = listByCondition(condition);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        // 客户联系电话
        CustomerDTO dto = list.get(0);
        CustomerTelCondition telCondition = new CustomerTelCondition();
        telCondition.setCustomerId(customerId);
        dto.setTels(customerTelService.listByCondition(telCondition));

        // 申贷记录
        CreditCondition creditCondition = new CreditCondition();
        creditCondition.setCustomerId(customerId);
        List<CreditVO> creditList = creditService.listByCondition(creditCondition);
        if (!CollectionUtils.isEmpty(creditList)) {
            List<CustomerCreditDTO> ccList = new ArrayList<>(creditList.size());
            for (CreditVO credit : creditList) {
                ccList.add(new CustomerCreditDTO(credit));
            }
            dto.setCredits(ccList);
        }
        return dto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateById(CustomerModifyReq req) {
        if (req.getId() == null) {
            return;
        }

        Customer customer = baseMapper.selectById(req.getId());
        if (customer == null) {
            return;
        }

        Customer updateCustomer = req.toCustomer();
        if (!req.getStatus().equals(customer.getStatus())) {
            updateCustomer.setStatusTime(new Date());
        }

        baseMapper.updateById(updateCustomer);

        customerTelService.deleteByCustomerId(req.getId(), req.getModifiedId(), req.getModifiedName());

        List<CustomerTel> tels = req.toCustomerTels(req.getId());
        if (!CollectionUtils.isEmpty(tels)) {
            customerTelService.saveBatch(tels);
        }

        customerTaxService.deleteByCustomerId(req.getId(), req.getModifiedId(), req.getModifiedName());
        List<CustomerTax> customerTaxList = req.getCustomerTaxes();
        if (!CollectionUtils.isEmpty(customerTaxList)) {
            customerTaxService.saveBatch(customerTaxList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSalesId(CustomerSalesDTO dto) {
        if (CollectionUtils.isEmpty(dto.getCustomerIdList())) {
            return;
        }
        baseMapper.updateSalesId(dto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSalesId(List<SalesQuantityReq> salesQuantityList) {
        if (CollectionUtils.isEmpty(salesQuantityList)) {
            return;
        }

        LambdaUpdateWrapper<Customer> updateWrapper = null;
        for (SalesQuantityReq salesQuantity : salesQuantityList) {
            if (!StringUtils.hasText(salesQuantity.getSalesId()) || salesQuantity.getQuantity() <= 0) {
                continue;
            }

            updateWrapper = new LambdaUpdateWrapper();
            updateWrapper.set(Customer::getSalesId, salesQuantity.getSalesId())
                .eq(Customer::getSalesId, "0")
                .eq(Customer::getIsDeleted, 0)
                .eq(Customer::getStatus, "01000")
                .last("limit " + salesQuantity.getQuantity());
            this.update(updateWrapper);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(CustomerAddReq req) {
        Customer customer = req.toCustomer();
        baseMapper.insert(customer);

        List<CustomerTel> tels = req.toCustomerTels(customer.getId());
        if (!CollectionUtils.isEmpty(tels)) {
            customerTelService.saveBatch(tels);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(List<CustomerImportExcel> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        Customer customer;
        List<Customer> customerList = new ArrayList<>();
        for (CustomerImportExcel dto : list) {

//            if (CustomerCache.getByName(dto.getName()) != null) {
//                // 客户已经存在
//                continue;
//            }

//            if (baseMapper.selectByName(dto.getName()) != null) {
//                //throw BusinessException.withErrorCode("客户名称已存在");
//                log.info("客户名称已存在, name: {}", dto.getName());
//                continue;
//            }

            customer = dto.toCustomer();
            customerList.add(customer);
            //baseMapper.insert(customer);

//            List<CustomerTel> telList = dto.toCustomerTels(customer.getId());
//            if (!CollectionUtils.isEmpty(telList)) {
//                customerTelService.saveBatch(telList);
//            }
        }

        if (CollectionUtils.isEmpty(customerList)) {
            return;
        }
        saveBatch(customerList);

        Map<String, Customer> customerMap = customerList.stream().collect(Collectors.toMap(Customer::getName, e -> e));
        List<CustomerTel> telList = new ArrayList<>();
        for (CustomerImportExcel dto : list) {
            if (customerMap.get(dto.getName()) != null) {
                if (!CollectionUtils.isEmpty(dto.toCustomerTels(customerMap.get(dto.getName()).getId()))) {
                    telList.addAll(dto.toCustomerTels(customerMap.get(dto.getName()).getId()));
                }
            }
        }
        if (!CollectionUtils.isEmpty(telList)) {
            customerTelService.saveBatch(telList, telList.size());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void moveStatus(CustomerMoveStatusDTO dto) {
        if (CollectionUtils.isEmpty(dto.getCustomerIds())) {
            return;
        }

        baseMapper.updateStatusByCustomerIds(dto);
    }

    @Override
    public List<SalesQuantityDTO> querySalesQuantity() {
        List<SalesQuantityDTO> dataList = new ArrayList<>();
        List<User> userList = userService.listByUserType("1");
        List<StaSalCustomerDTO> customerList = statisticMapper.selectListForStaSalCustomer();
        Map<String, StaSalCustomerDTO> salesMap = null;
        if (!CollectionUtils.isEmpty(customerList)) {
            salesMap = customerList.stream().collect(Collectors.toMap(StaSalCustomerDTO::getSalesId, e -> e));
        }
        for (User user : userList) {
            SalesQuantityDTO dto = new SalesQuantityDTO();
            dto.setSalesId(user.getUserId());
            dto.setSalesName(user.getUserName());

            if (salesMap != null && salesMap.get(user.getUserId()) != null) {
                dto.setCustomerCount(salesMap.get(user.getUserId()).getCustomerCount());
            }

            dataList.add(dto);
        }

        return dataList;
    }
}
